1 load libraries

2 define helper functions

fun_dot <- function(x) format(x, big.mark = " ",
                              scientific = FALSE,
                              decimal.mark = ".")

# negative in
`%!in%` <- Negate(`%in%`)

# y scale
log10_minor_break = function (...){
  function(x) {
    minx         = floor(min(log10(x), na.rm=T))-1;
    maxx         = ceiling(max(log10(x), na.rm=T))+1;
    n_major      = maxx-minx+1;
    major_breaks = seq(minx, maxx, by=1)
    minor_breaks = 
      rep(log10(seq(1, 9, by=1)), times = n_major)+
      rep(major_breaks, each = 9)
    return(10^(minor_breaks))
  }
}

# for conditionaly filtering
# (from: https://github.com/tidyverse/magrittr/issues/109#issuecomment-371999796)
conditionally <- function(fun){
    function(first_arg, ..., execute){
        if(execute) return(fun(first_arg, ...))
        else return(first_arg)
    }
}
cond_filter <- conditionally(filter)
cond_select <- conditionally(select)

3 load data

4 wrangle

df <- df %>% group_by(Countries_territories) %>% 
  mutate(Cum_Cases = cumsum(Daily_Cases), 
         Cum_Deaths = cumsum(Daily_Deaths))
df <- df %>%
  pivot_longer(cols = c(Daily_Cases, Daily_Deaths, Cum_Cases, Cum_Deaths), 
               names_to = "Category")

df$Countries_territories <- str_replace_all(df$Countries_territories, "_", " ")
df <- df %>% mutate(
  Continent=countrycode(Countries_territories,
                        origin = "country.name",
                        destination = "continent"),
  Continent=if_else(Countries_territories=="Kosovo", 
                    "Europe", Continent),
  Continent=if_else(Continent == "Oceania", "Asia", Continent))
## Warning in countrycode(Countries_territories, origin = "country.name", destination = "continent"): Some values were not matched unambiguously: Kosovo

5 define plot function

gen_df_to_plot <- function(data, filter_location, null_day_threshold, filter_category) {

  # gen data to plot
  df %>% 
    group_by(Countries_territories) %>% 
    filter(Category == filter_category) %>% 
    filter(value >= null_day_threshold) %>% 
    mutate(date_shift=0:(n()-1)/7) %>% # generate date shifted after null_day_threshold
    ungroup(Countries_territories) %>% 
    arrange(Continent, Countries_territories, date_shift) %>% 
    filter(toupper(Countries_territories) %in% toupper(filter_location) | Continent %in% filter_location)
}

gen_plot <- function(data, filter_location,
                     filter_category="Cum_Cases",
                     null_day_threshold=1,
                     emph_color="red") {
  
  df_to_plot <- gen_df_to_plot(data = data,
                               filter_location,
                               filter_category,
                               null_day_threshold = null_day_threshold)
  
  df_to_plot$Countries_territories_bkg <- df_to_plot$Countries_territories
  nr_end <- case_when(null_day_threshold %% 10 == 1 ~ "st ", 
                      null_day_threshold %% 10 == 2 ~ "nd ",
                      null_day_threshold %% 10 == 3 ~ "rd ", 
                      TRUE ~ "th ")
  
  # plot descriptions
  updated_at <- data$Date %>% max() %>% format("%b %d")
  
  gg_category <- ifelse(filter_category=="Cum_Deaths", "death", "case")
  gg_title <- "Evolution of COVID-19"
  gg_subtitle <- paste0("Cumulative ", gg_category, "s since ", null_day_threshold, nr_end, gg_category,
                        " (log scale, updated on ", updated_at, ")") %>%
    tools::toTitleCase()
  gg_x_name <- paste0("Weeks past since ", null_day_threshold, nr_end, gg_category) %>%
    tools::toTitleCase()
  gg_caption <- "Data Source: https://www.ecdc.europa.eu"
  
  # plot
  df_to_plot %>% 
    ggplot(aes(x=date_shift, y=value, group=Countries_territories)) +
    geom_line(data=df_to_plot[, c("date_shift", "value", "Countries_territories_bkg")],
              aes(x=date_shift, y=value, group=Countries_territories_bkg), 
              color="grey") +
    geom_line(color = emph_color) + geom_point(color = emph_color, size=1/2) +
    facet_wrap(~Countries_territories) +
    
    #title
    labs(title=gg_title, subtitle=gg_subtitle, caption=gg_caption) +
    scale_y_log10(labels=fun_dot, breaks = 10^(0:9), minor_breaks=log10_minor_break()) + 
    scale_x_continuous(name=gg_x_name, breaks=seq(0, 1e3, 1), minor_breaks=1:1e3/7)
}
gg_theme <- theme(legend.position = "none",
        axis.title.y = element_blank(),
        axis.text=element_text(size=rel(1)),
        plot.title = element_text(size=rel(3)),
        plot.subtitle = element_text(size=rel(2)))

6 plot for selected countries

filter_countries <- c("Brazil", "Germany", "Italy", "South Korea", 
                      "Spain", "France", "Iran", "Japan", "Singapore",
                      "India", "United states of america", "United kingdom", 
                      "Russia", "Chile", "Colombia", "Portugal")

for (cat in c("Cum_Cases", "Cum_Deaths")) {
  threshold <- ifelse(cat=="Cum_Cases", 100, 1 )
  
  p <- gen_plot(df, filter_location = filter_countries, emph_color = "red", 
           null_day_threshold = threshold, 
           filter_category = cat) + 
    gg_theme
  print(p)
}

7 plot for selected continents

for (cat in c("Cum_Cases", "Cum_Deaths")) {
  threshold <- ifelse(cat=="Cum_Cases", 50, 1 )
  for (cont in unique(df$Continent)) {
    p <- gen_plot(df,
                  filter_location = cont,
                  emph_color = "red", 
                  null_day_threshold = threshold, 
                  filter_category = cat) + gg_theme
    print(p)
  }
}